/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package connection;

import java.io.DataInputStream;
import java.io.PrintStream;
import java.net.Socket;
import utils.Debug;
import utils.StringHelper;
import java.util.Vector;

/**
 *
 * @author daz
 */
public class DataTransfer implements Runnable {

    public static DataTransfer dataTransfer;
//    private String serverHost = "202.92.4.22";
//    private int serverPort = 6666;
    private String serverHost = "localhost";
    private int serverPort = 9000;
//    private String serverHost = "118.70.67.167";
//    private String serverPort = "1602";
    private MasterServer masterServer;
    private boolean isConnect = true;
    public Vector dataInputQueue;
    private IMessageListenner messageListenner;
    private PrintStream dataOutputStream;
    private DataInputStream dataInputStream;
    private ReaderThread reader;
    private boolean isRunning;
    private String myName = "";

    public DataTransfer() {
        Debug.d("new datatranfer");
        isConnect = createConnection();
    }

    public static DataTransfer getInstance() {
        if (dataTransfer == null) {
            dataTransfer = new DataTransfer();
        }
        return dataTransfer;
    }

    public DataTransfer(String host, String port) {
        Debug.d("new datatranfer");
        this.serverHost = host;
        this.serverPort = Integer.parseInt(port);
        isConnect = createConnection();
    }

    public void setMessageListenner(IMessageListenner messageLinner) {
        this.messageListenner = messageLinner;
        if (!isConnect) {
            dataTransfer = null;
        }
    }

    public boolean isConnect() {
        return this.isConnect;
    }

    private boolean createConnection() {
        try {
            Socket socket = null;
            socket = new Socket(serverHost, serverPort);
//            socket.setSocketOption(socket.RCVBUF, 16384);
            dataInputQueue = new Vector();
            dataOutputStream = new PrintStream(socket.getOutputStream());
            dataInputStream = new DataInputStream(socket.getInputStream());
            startThread();
            return true;
        } catch (Exception ex) {
            Debug.d("connect failed");
            return false;
        }
    }

    private void startThread() {
        reader = new ReaderThread(dataInputStream, this);
        isRunning = true;
        new Thread(this).start();
    }

    public void request(String message) {
        Debug.d(myName + "-send :" + message);
        try {
            byte[] outMsg = null;
            int dataLength = message.getBytes("UTF-8").length + 2;
//            Debug.d("data length :" + dataLength);
            outMsg = new byte[dataLength];
            System.arraycopy(message.getBytes("UTF-8"), 0, outMsg, 1, dataLength - 2);
            outMsg[0] = 125;
            outMsg[dataLength - 1] = 38;
            dataOutputStream.write(outMsg);
            dataOutputStream.flush();
        } catch (Exception ex) {
        }
    }

    @Override
    public void run() {
        while (isRunning) {
            if (dataInputQueue.size() > 0 && isConnect) {
                String message = (String) dataInputQueue.elementAt(0);
                Debug.d(myName + "-Receive:" + message);
                String[] part = StringHelper.split(message, '|');
                messageListenner.processMessage(part);
                dataInputQueue.removeElementAt(0);
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    public void quit() {
        String[] part = {"QUIT"};
        messageListenner.processMessage(part);
    }

    public void stop() {
        isConnect = false;
        if (this.messageListenner != null) {
            messageListenner.stop();
        }
    }

    public static void releaseConnection() {
        if (dataTransfer != null) {
            dataTransfer.stop();
        }
        dataTransfer = null;
        Runtime.getRuntime().gc();
    }

    public void setMyName(String name) {
        this.myName = name;
    }
}
